﻿package com.gobang.aimode.aiengine;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import com.gobang.gobangui.MainWindowUI;
import com.gobang.util.chessdata.ChessPoint;

public class CreatePossibleMove {

	final static int N = 15, BLACK = 1, WHITE = 2;
	private int MaxWight;
	private int computerRole;
	private int nowPlayer;
	private int[][] forecastChessboard = new int[17][17];
	private Stack<ChessPoint> chessStack = new Stack<ChessPoint>(); //棋子堆栈
	List<ChessPoint> possibleMoveList = new ArrayList<ChessPoint>();
	
	private int[][][] score = new int[3][16][16];
	private int[][][][] chessPointStyle = new int[3][16][16][4];
	private int[][] pointScore = new int[16][16]; //防守、攻击的总分
	private int[] scope = new int[5];   //搜索范围
	
	public List<ChessPoint> getPossibleMoveList() {
		return possibleMoveList;
	}
	
	public CreatePossibleMove(int[][] forecastChessboard, 
			Stack<ChessPoint> chessStack, int nowPlayer) {
		InitializeBoard(forecastChessboard, chessStack,nowPlayer);
		setScope();
		chessModel();
		SetPointScore();
		this.possibleMoveList = Sort(possibleMoveList);  //排序
	}
	
	public List<ChessPoint> Sort(List<ChessPoint> possibleMove) {
		
		ChessPoint tempChessPoint;
		for (int i = 0; i < MaxWight; i++) {
			int k = i;
			for (int j = i + 1; j < possibleMove.size(); j++) {
				if (possibleMove.get(k).getSore() < possibleMove.get(j).getSore()) {
					k = j;
				}
			}
			if (k != i) {
				tempChessPoint = possibleMove.get(k);
				possibleMove.set(k, possibleMove.get(i));
				possibleMove.set(i, tempChessPoint);
			}
		}
		List<ChessPoint> sortPossibleMove = new ArrayList<ChessPoint>();
		for (int i = 0; i < MaxWight; i++) {
			sortPossibleMove.add(possibleMove.get(i));
		}
		return sortPossibleMove;
	}
	
	private void InitializeBoard(int[][] forecastChessboard, Stack<ChessPoint> chessStack, int nowPlayer) {
		
		for (int i = 1; i <= 15; i++) {                   //初始化分值
			for (int j = 1; j <= 15; j++) {
				this.forecastChessboard[i][j] = forecastChessboard[i][j];
				int distance = Math.abs(i - 8) > Math.abs(j - 8) ? Math.abs(i - 8) : Math.abs(j - 8);
				pointScore[i][j] = 7 - distance;
			}
		}
		computerRole = MainWindowUI.getLocalPlayFrame().getComputerRole();
		this.chessStack = chessStack;
		this.nowPlayer = nowPlayer;
		MaxWight = MainWindowUI.getLocalPlayFrame().getMaxWight();
	}
	
	public void SetPointScore() {
		for (int pointY = scope[2]; pointY <= scope[4]; pointY++) {
			for (int pointX = scope[1]; pointX <= scope[3]; pointX++) {
				for (int color = BLACK; color <= WHITE; color++) {
					for (int dir = 0; dir < 4; dir++) {
						score[color][pointX][pointY] += chessPointStyle[color][pointX][pointY][dir];
					}
				}
				pointScore[pointX][pointY] += 
						score[computerRole][pointX][pointY] - score[3 -computerRole][pointX][pointY];
				possibleMoveList.add(new ChessPoint(pointX, pointY, nowPlayer, 
						score[computerRole][pointX][pointY] + score[3 -computerRole][pointX][pointY]));
				
			}
		}
	}
	
	public void setScope() {
		scope[1] = scope[2] = 15;  //初始化搜索框四边坐标
		scope[3] = scope[4] = 1;

		for (ChessPoint tempChessStack : chessStack) {   //棋盘已经落子的范围
			int X = tempChessStack.getX();
			int Y = tempChessStack.getY();
			if (X < scope[1]) scope[1] = X;
			if (X > scope[3]) scope[3] = X;
			if (Y < scope[2]) scope[2] = Y;
			if (Y > scope[4]) scope[4] = Y;
		}
		for (int j = 1; j <= 2; j++) {
			for (int i = 1; i <= 2; i++) {
				if (scope[i] - 1 > 0) {
					scope[i]--;
				}
			}
			for (int i = 3; i <= 4; i++) {
				if (scope[i] + 1 <= 15){
					scope[i]++;
				}
			}
		}
	}
	
	public void chessModel() {

		for (int pointY = scope[2]; pointY <= scope[4]; pointY++) {
			for (int pointX = scope[1]; pointX <= scope[3]; pointX++) {
				for (int color = BLACK; color <= WHITE; color++) {
					if (forecastChessboard[pointX][pointY] == 0) {
						forecastChessboard[pointX][pointY] = color;
						
						int contiue = 0, colorNumber = 0, blank = 0, gap = 0, lenth = 1, tempLenth, i;
						boolean isContinue = true, isLenthEnd = false, left = false, right = false; //是否连续，是否开放
						
						/**
						 * 横向检测
						 */
						for(i = 0; i <= 4 && pointX - i > 0 ; i++){   //向左检查
							
							if (forecastChessboard[pointX - i][pointY] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointX - i - 1 > 0 && forecastChessboard[pointX - i - 1][pointY] == 0){
										left = true;
									}
								}
								if (isContinue) {
									contiue++;
								}
							}else if (forecastChessboard[pointX - i][pointY] == 0) {
								blank++;
								isContinue = false;
								if (pointX-i - 1 <= 0) {  //边界情况
									left = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX - i - 1][pointY] != color) {
									left = true;
									if (forecastChessboard[pointX - i - 2][pointY] != color || i + 2 > 4){
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							}else if (forecastChessboard[pointX - i][pointY] == 3 - color){
								lenth += i - 1;
								break;
							}
						}
						tempLenth = lenth;
						for (i = 1; i < tempLenth; i++) {
							if (forecastChessboard[pointX - i][pointY] == 0) {
								gap++;
							}
						}
						isContinue = true;
						isLenthEnd = false;
						
						for(i = 0; i <= 4 && pointX + i <= N; i++){             //向右检查
							if (forecastChessboard[pointX + i][pointY] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointX + i + 1 <= N && forecastChessboard[pointX + i + 1][pointY] == 0){
										right = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX + i][pointY] == 0) {
								blank++;
								isContinue = false;
								if (pointX+ i + 1 > 15) {  //边界情况
									right = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX + i + 1][pointY] != color) {
									right = true;
									if (forecastChessboard[pointX + i + 2][pointY] != color || i + 2 > 4) {
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							} else if (forecastChessboard[pointX + i][pointY] == 3 - color) {
								lenth += i - 1;
								break;
							}
						}
						for (i = 1; i < lenth - tempLenth; i++) {
							if (forecastChessboard[pointX + i][pointY] == 0) {
								gap++;
							}
						}
						setChessPointStyle(color, pointX, pointY, 0, contiue - 1, colorNumber - 1, blank, gap, lenth, left, right);
						
						/**
						 *   "\"斜检测
						 */
						isContinue = true;
						left = right = isLenthEnd = false;
						contiue = colorNumber = blank = gap = 0;
						lenth = 1;
						for(i = 0; i <= 4 && pointX + i<= N && pointY + i <= N; i++){ //向右下检查
							if (forecastChessboard[pointX+i][pointY+i] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointX + i + 1<= N && pointY + i + 1<= N 
											&& forecastChessboard[pointX+i + 1][pointY+i + 1] == 0){
										left = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX+i][pointY+i] == 0) {
								blank++;
								isContinue = false;
								if (pointX+i + 1 > 15 || pointY+i +1 > 15) {  //边界情况
									left = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX + i + 1][pointY+i + 1] != color) {
									left = true;
									if (forecastChessboard[pointX + i + 2][pointY+i + 2] != color || i + 2 > 4) {
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							} else if (forecastChessboard[pointX+i][pointY+i] == 3 - color){
								lenth += i - 1;
								break;
							}
						}
						tempLenth = lenth;
						for (i = 1; i < tempLenth; i++) {
							if (forecastChessboard[pointX+i][pointY+i] == 0) {
								gap++;
							}
						}
						isContinue = true;
						isLenthEnd = false;
						for(i = 0; i <= 4 && pointX - i > 0 && pointY - i > 0; i++){ //向左上检查
							if (forecastChessboard[pointX-i][pointY-i] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointX - i - 1> 0 && pointY - i - 1 > 0 
											&& forecastChessboard[pointX-i - 1][pointY-i - 1] == 0){
										right = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX-i][pointY-i] == 0) {
								blank++;
								isContinue = false;
								if (pointX-i - 1 <= 0 || pointY-i -1 <= 0) {  //边界情况
									right = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX-i - 1][pointY-i - 1] != color) {
									right = true;
									if (forecastChessboard[pointX-i - 2][pointY-i - 2] != color || i + 2 > 4) {
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							} else if (forecastChessboard[pointX-i][pointY-i] == 3 - color) {
								lenth += i - 1;
								break;
							}
						}
						for (i = 1; i < lenth - tempLenth; i++) {
							if (forecastChessboard[pointX-i][pointY-i] == 0) {
								gap++;
							}
						}
						setChessPointStyle(color, pointX, pointY, 1, contiue - 1, colorNumber - 1, blank, gap, lenth, left, right);

						/**
						 * 纵向检测
						 */
						
						isContinue = true;
						left = right = isLenthEnd = false;
						contiue = colorNumber = blank = gap = 0;
						lenth = 1;
						for(i = 0; i <= 4 && pointY + i <= N; i++){ //向下检查
							if (forecastChessboard[pointX][pointY + i] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointY + i + 1 <= N && forecastChessboard[pointX][pointY + i + 1] == 0){
										left = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX][pointY + i] == 0) {
								blank++;
								isContinue = false;
								if (pointY + i + 1 > 15) {  //边界情况
									left = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX][pointY + i + 1] != color) {
									left = true;
									if (forecastChessboard[pointX][pointY + i + 2] != color || i + 2 > 4) {
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							} else if (forecastChessboard[pointX][pointY + i] == 3 - color) {
								lenth += i - 1;
								break;
							}
						}
						tempLenth = lenth;
						for (i = 1; i < tempLenth; i++) {
							if (forecastChessboard[pointX][pointY + i] == 0) {
								gap++;
							}
						}
						isContinue = true;
						isLenthEnd = false;
						for(i = 0; i <= 4 && pointY - i> 0; i++){ //向上检查
							if (forecastChessboard[pointX][pointY - i] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointY - i - 1> 0 && forecastChessboard[pointX][pointY - i - 1] == 0){
										right = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX][pointY - i] == 0) {
								blank++;
								isContinue = false;
								if (pointY-i -1 <= 0) {  //边界情况
									right = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX][pointY - i - 1] != color) {
									right = true;
									if (forecastChessboard[pointX][pointY - i - 2] != color || i + 2 > 4){
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							}else if (forecastChessboard[pointX][pointY - i ] == 3 - color) {
								lenth += i - 1;
								break;
							}
						}
						for (i = 1; i < lenth - tempLenth; i++) {
							if (forecastChessboard[pointX][pointY - i] == 0) {
								gap++;
							}
						}
						setChessPointStyle(color, pointX, pointY, 2, contiue - 1, colorNumber - 1, blank, gap, lenth, left, right);
						
						/**
						 *   "/"斜检测
						 */
						isContinue = true;
						left = right = isLenthEnd = false;
						contiue = colorNumber = blank = gap = 0;
						lenth = 1;
						for(i = 0; i <= 4 && pointX + i <= N && pointY - i > 0; i++){ //向右上检查
							if (forecastChessboard[pointX+i][pointY-i] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointX + i + 1 <= N && pointY - i - 1 > 0 
											&& forecastChessboard[pointX + i + 1][pointY-i - 1] == 0){
										left = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX+i][pointY-i] == 0) {
								blank++;
								isContinue = false;
								if (pointX + i + 1 > 15 || pointY-i -1 <= 0) {  //边界情况
									left = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX+i + 1][pointY-i - 1] != color) {
									left = true;
									if (forecastChessboard[pointX+i + 2][pointY-i - 2] != color || i + 2 > 4){
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							} else if (forecastChessboard[pointX+i][pointY-i] == 3 - color) {
								lenth += i - 1;
								break;
							}
						}
						tempLenth = lenth;
						for (i = 1; i < tempLenth; i++) {
							if (forecastChessboard[pointX+i][pointY-i] == 0) {
								gap++;
							}
						}
						isContinue = true;
						isLenthEnd = false;
						
						for(i = 0; i <= 4 && pointX - i > 0 && pointY + i <= N; i++){ //向左下检查
							if (forecastChessboard[pointX-i][pointY+i] == color) {
								colorNumber++;
								if (i == 4) {
									lenth += 4;
									if (pointX - i - 1 > 0 && pointY + i + 1 <= N 
											&& forecastChessboard[pointX-i - 1][pointY+i + 1] == 0){
										right = true;
									}
								}
								if (isContinue) {
									contiue++;
								} 
							}else if (forecastChessboard[pointX-i][pointY+i] == 0) {
								blank++;
								isContinue = false;
								if (pointX-i - 1 <= 0 || pointY + i + 1 > 15) {  //边界情况
									right = true;
									if (!isLenthEnd) {
										lenth += i - 1;
									}
									break;
								}
								if (forecastChessboard[pointX-i -1][pointY+i + 1] != color) {
									right = true;
									if (forecastChessboard[pointX - i - 2][pointY+i + 2] != color || i + 2 > 4){
										if (!isLenthEnd) {
											isLenthEnd = true;
											lenth += i - 1;
										}
									}
								}
							} else if (forecastChessboard[pointX-i][pointY+i] == 3 - color) {
								lenth += i - 1;
								break;
							}
						}
						for (i = 1; i < lenth - tempLenth; i++) {
							if (forecastChessboard[pointX-i][pointY+i] == 0) {
								gap++;
							}
						}
						setChessPointStyle(color, pointX, pointY, 3, contiue - 1, colorNumber - 1, blank, gap, lenth, left, right);
						
						forecastChessboard[pointX][pointY] = 0;
					}
				}

			}
		}
	}
	
	public void setChessPointStyle(int color, int pointX, int pointY, int dir, 
			int contiue, int colorNumber, int blank, int gap, int lenth, boolean left, boolean right) {
		if (color == nowPlayer) {
			
			if (contiue >= 5 ) { 					       //1成五
				chessPointStyle[color][pointX][pointY][dir] = 100000;

			} else if (contiue == 4 
					&& ((left && right) || (lenth >= 6 && colorNumber >= 5 && gap >= 1)) ) {  //2活四
				chessPointStyle[color][pointX][pointY][dir] = 5000;
			} else if (gap <= 1 && colorNumber >= 4 && blank >= 1
					&&((left^right) || (left && right))){    //3冲四
				chessPointStyle[color][pointX][pointY][dir] = 2100;

			} else if (contiue == 3 
					&& ((left && right) || (lenth >= 5 && colorNumber >= 4 && gap >= 1)) ){    //4连活三
				chessPointStyle[color][pointX][pointY][dir] = 1800;
			} else if (gap <= 1 && colorNumber >= 3 && left && right){    //5跳活三
				chessPointStyle[color][pointX][pointY][dir] = 1200;
			} else if (contiue == 3 && blank >= 2 && (left^right) ){    //6眠三
				chessPointStyle[color][pointX][pointY][dir] = 600;

			} else if (contiue == 2 && blank >= 3 && left && right){    //7连活二
				chessPointStyle[color][pointX][pointY][dir] = 300;
			} else if (gap <= 2 && colorNumber >= 2 && blank >= 3 && left && right){    //8(大)跳活二
				chessPointStyle[color][pointX][pointY][dir] = 230;
			} else if (contiue == 2 && blank >= 3 && (left^right) ){    //9眠二
				chessPointStyle[color][pointX][pointY][dir] = 100;

			} else if (contiue == 1 && blank >= 4 && left && right){    //10活一
				chessPointStyle[color][pointX][pointY][dir] = 50;
			} else if (contiue == 1 && blank >= 1 && (left^right) ){    //11眠一
				chessPointStyle[color][pointX][pointY][dir] = 15;
			} 
		} else if (color == 3 - nowPlayer){
			
			
			if (contiue >= 5 ) { 					       //1成五
				chessPointStyle[color][pointX][pointY][dir] = 10000;

			} else if (contiue == 4 
					&& ((left && right) || (lenth >= 6 && colorNumber >= 5 && gap >= 1)) ) {  //2活四
				chessPointStyle[color][pointX][pointY][dir] = 3000;
			} else if (gap <= 2 && colorNumber >= 4 && blank >= 1
					&&((left^right) || (left && right))){    //3冲四
				chessPointStyle[color][pointX][pointY][dir] = 1800;

			} else if (contiue == 3 
					&& ((left && right) || (lenth >= 5 && colorNumber >= 4 && gap >= 1)) ){    //4连活三
				chessPointStyle[color][pointX][pointY][dir] = 1200;
			} else if (gap <= 1 && colorNumber >= 3 && left && right){     //5(大)跳活三
				chessPointStyle[color][pointX][pointY][dir] = 1000;
			} else if (contiue == 3 && blank >= 2 && (left^right) ){    //6眠三
				chessPointStyle[color][pointX][pointY][dir] = 480;

			} else if (contiue == 2 && blank >= 3 && left && right){    //7连活二
				chessPointStyle[color][pointX][pointY][dir] = 240;
			} else if (gap <= 2 && colorNumber >= 2 && blank >= 3 && left && right){   //8(大)跳活二
				chessPointStyle[color][pointX][pointY][dir] = 200;
			} else if (contiue == 2 && blank >= 3 && (left^right) ){    //9眠二
				chessPointStyle[color][pointX][pointY][dir] = 80;

			} else if (contiue == 1 && blank >= 4 && left && right){    //10活一
				chessPointStyle[color][pointX][pointY][dir] = 40;
			} else if (contiue == 1 && blank >= 1 && (left^right) ){    //11眠一
				chessPointStyle[color][pointX][pointY][dir] = 10;
			} 
		} else {
			System.err.println("setChessPointStyle error");
		}
	}
	
}